import {_decorator, Color, Component, director, Label, tween, UIOpacity, Vec3} from "cc";
import {utils} from "db://assets/script/utils/utils";
import {GameEvent} from "db://assets/script/game-event";
import {FreshImmortal} from "../../../proto/shared/v1/wuni";
import {DamageType} from "db://assets/script/game/battle/damage-type";
import randomInt = utils.randomInt;
import Long from "long";

const {ccclass, property} = _decorator;

// 伤害数字组件
@ccclass('DamageNumber')
export class DamageNumber extends Component {


    @property(Label)
    label: Label = null!;
    moveStopTimeMs: number = 0.5;
    showTimeMs: number = 1.5;
    finalOpacity: number = 0.5;
    private uiOpacity: UIOpacity = null!;
    tweenMap = new Map<number, (damage: string, position: Vec3) => void>([
        [DamageType.NORMAL_DAMAGE_TYPE, this.normalDamageFunc],
        [DamageType.CT_NORMAL_DAMAGE_TYPE, this.ctNormalDamageFunc],
        [DamageType.REAL_DAMAGE_TYPE, this.realDamageFunc],
        [DamageType.GOLD_DAMAGE_TYPE, this.jinDamageFunc],
        [DamageType.WOOD_DAMAGE_TYPE, this.muDamageFunc],
        [DamageType.WATER_DAMAGE_TYPE, this.shuiDamageFunc],
        [DamageType.FIRE_DAMAGE_TYPE, this.huoDamageFunc],
        [DamageType.EARTH_DAMAGE_TYPE, this.tuDamageFunc],
        [DamageType.DODGE_TYPE, this.dodgeFunc],
        [DamageType.NORMAL_RECOVER_TYPE, this.normalRecoverFunc],
        [DamageType.NORMAL_MAGIC_POWER_RECOVER_TYPE, this.normalEnergyRecoverFunc],
        [DamageType.SUCK_BLOOD_RECOVER_TYPE, this.suckBloodRecoverFunc],
        [DamageType.EXPLORE_TYPE, this.exploreFunc],
        [DamageType.LEVEL_UP_TYPE, this.levelUpFunc],
    ])

    levelUpFunc(damage: string, position: Vec3) {
        this.label.string = damage;
        Color.fromHEX(this.label.color, "#FFFFFF")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x, this.node.position.y + 150)})
            .parallel(
                tween(this.node)
                    .to(this.moveStopTimeMs, {scale: new Vec3(1.3, 1.3, 1.3)})
            )
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    exploreFunc(damage: string, position: Vec3) {
        this.label.string = damage;
        Color.fromHEX(this.label.color, "#FFFFFF")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x, this.node.position.y + 150)})
            .parallel(
                tween(this.node)
                    .to(this.moveStopTimeMs, {scale: new Vec3(1.3, 1.3, 1.3)})
            )
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    normalDamageFunc(damage: string, position: Vec3): void {
        this.label.string = damage;
        Color.fromHEX(this.label.color, "#FFB90F")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    ctNormalDamageFunc(damage: string, position: Vec3): void {
        this.label.string = '暴击: ' + damage;
        Color.fromHEX(this.label.color, "#CD5555")
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 150)})
            .parallel(
                tween(this.node)
                    .to(0.4 * this.moveStopTimeMs, {scale: new Vec3(2, 2, 2)})
                    .to(0.6 * this.moveStopTimeMs, {scale: new Vec3(1, 1, 1)})
            )
            .tag(1000)
            .start();


        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    realDamageFunc(damage: string, position: Vec3): void {
        this.label.string = damage;
        Color.fromHEX(this.label.color, "#FFFFFF")
        // // console.log("damage init position: " + position)
        this.node.position = position
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    jinDamageFunc(damage: string, position: Vec3): void {
        this.label.string = '金: ' + damage;
        Color.fromHEX(this.label.color, "#FFD700")
        // // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(0.5, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    muDamageFunc(damage: string, position: Vec3): void {
        this.label.string = '木: ' + damage;
        Color.fromHEX(this.label.color, "#DEB887")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    shuiDamageFunc(damage: string, position: Vec3): void {
        this.label.string = '水: ' + damage;
        Color.fromHEX(this.label.color, "#87CEFA")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    huoDamageFunc(damage: string, position: Vec3): void {
        this.label.string = '火: ' + damage;
        Color.fromHEX(this.label.color, "#B22222")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    tuDamageFunc(damage: string, position: Vec3): void {
        this.label.string = '土: ' + damage;
        Color.fromHEX(this.label.color, "#CD853F")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    dodgeFunc(damage: string, position: Vec3): void {
        this.label.string = '闪避';
        Color.fromHEX(this.label.color, "#FFFFFF")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    normalRecoverFunc(damage: string, position: Vec3): void {
        this.label.string = damage;
        Color.fromHEX(this.label.color, "#32CD32")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    normalEnergyRecoverFunc(damage: string, position: Vec3): void {
        this.label.string = damage;
        Color.fromHEX(this.label.color, "#3297cd")
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    suckBloodRecoverFunc(damage: string, position: Vec3): void {
        this.label.string = '吸血: ' + damage;
        Color.fromHEX(this.label.color, "#32CD32")
        // console.log("damage init position: " + position)
        this.node.position = position
        this.label.enableOutline = true
        this.label.isBold = true

        const rdX = randomInt(-100, 100)
        tween(this.node)
            .to(this.moveStopTimeMs, {position: new Vec3(this.node.position.x + rdX, this.node.position.y + 100)})
            .tag(1000)
            .start();

        tween(this.uiOpacity)
            .to(this.showTimeMs, {opacity: this.finalOpacity})
            .call(() => this.node.destroy())
            .tag(1000)
            .start();
    }

    start() {
        director.on(GameEvent.changeBattleRole, (fishId: Long) => {
            this.node.destroy()
        }, this)
    }

    protected onDestroy(): void {
        director.off(GameEvent.changeBattleRole, (fishId: Long) => {
            this.node.destroy()
        }, this)
    }


    onLoad() {
        this.uiOpacity = this.getComponent(UIOpacity)! || this.addComponent(UIOpacity);

    }

    init(damage: string, position: Vec3, labelType: number) {
        this.tweenMap.get(labelType)!.call(this, damage, position);
    }

    update(deltaTime: number) {

    }
}

